package com.ecmcloud.flow.service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.flowable.engine.HistoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.task.api.DelegationState;
import org.flowable.task.api.Task;
import org.flowable.task.api.TaskQuery;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ecmcloud.common.dto.TaskParamDto;
import com.ecmcloud.common.dto.TaskResultDto;
import com.ecmcloud.common.dto.VariableQueryParamDto;
import com.ecmcloud.common.exception.WorkflowException;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;

@Service
public class WorkflowTaskService {

	@Autowired
	private TaskService taskService;
	
	@Autowired
	private HistoryService historyService;

	@Autowired
	private RuntimeService runtimeService;
	
	/**
	 * 查询任务变量
	 * @param paramDto
	 * @return
	 */
	public Map<String, Object> queryTaskVariables(VariableQueryParamDto paramDto) {
		List<String> keyList = paramDto.getKeyList();
		if (CollUtil.isEmpty(keyList)) {
			TaskQuery taskQuery = taskService.createTaskQuery();
			Task task = taskQuery.taskId(paramDto.getTaskId()).singleResult();
			if (task == null) {
				throw new WorkflowException("任务不存在");
			}
			Map<String, Object> variables = runtimeService.getVariables(task.getExecutionId());
			return variables;
		}
		Map<String, Object> variables = taskService.getVariables(paramDto.getTaskId(), keyList);
		return variables;
	}
	
	public TaskResultDto queryTask(String taskId, String userId) {
		DelegationState delegationState = null;
		/**
		 * 实例id
		 */
		String processInstanceId = null;
		Object delegateVariable = false;
		String processDefinitionId = null;
		/**
		 * nodeid
		 */
		String taskDefinitionKey = null;
		boolean taskExist = true;
		TaskQuery taskQuery = taskService.createTaskQuery();
		Task task = taskQuery.taskId(taskId).taskAssignee(userId).singleResult();
		if (task == null) {
			HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskId(taskId).taskAssignee(userId).singleResult();
			if (historicTaskInstance == null) {
				throw new WorkflowException("任务不存在");
			}
			taskExist = false;
			taskDefinitionKey = historicTaskInstance.getTaskDefinitionKey();
			processInstanceId = historicTaskInstance.getProcessInstanceId();
			processDefinitionId = historicTaskInstance.getProcessDefinitionId();
		} else {
			processDefinitionId = task.getProcessDefinitionId();
			taskDefinitionKey = task.getTaskDefinitionKey();
			delegationState = task.getDelegationState();
			processInstanceId = task.getProcessInstanceId();
			delegateVariable = taskService.getVariableLocal(taskId, "delegate");
		}
		/**
		 * 流程id
		 */
		String flowId = com.ecmcloud.flow.utils.NodeUtil.getFlowId(processDefinitionId);
		Map<String, Object> variableAll = new HashMap<>();
		/**
		 * 表单处理
		 */
		if (taskExist) {
			Map<String, Object> variables = taskService.getVariables(taskId);
			variableAll.putAll(variables);
		}
		TaskResultDto taskResultDto = new TaskResultDto();
		taskResultDto.setFlowId(flowId);
		taskResultDto.setNodeId(taskDefinitionKey);
		taskResultDto.setCurrentTask(taskExist);
		taskResultDto.setDelegate(Convert.toBool(delegateVariable, false));
		taskResultDto.setVariableAll(variableAll);
		taskResultDto.setProcessInstanceId(processInstanceId);
		taskResultDto.setDelegationState(delegationState == null ? null : delegationState.toString());
		return taskResultDto;
	}
	
	/**
	 * 完成任务
	 * @param taskParamDto
	 */
	public void complete(TaskParamDto taskParamDto) {
		Map<String, Object> taskLocalParamMap = taskParamDto.getTaskLocalParamMap();
		if (CollUtil.isNotEmpty(taskLocalParamMap)) {
			taskService.setVariablesLocal(taskParamDto.getTaskId(), taskLocalParamMap);
		}
		taskService.complete(taskParamDto.getTaskId(), taskParamDto.getParamMap());
	}
}
